package AIExtended;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import BackgammonBot.JGammon.AIMove;
import jgam.Move;
import jgam.Player;
import jgam.SingleMove;

public class AIPlayer extends Player 
{
	// IMPORTANT: You have to change these Fields with yours own filepaths
	private String inputFilePath;
	private String outputFilePath;
	private String pathToProgram;
	private Integer runtimeInMilli = 3000;
	
	
	public AIPlayer(String name
			, String inputFilePath
			, String outputFilePath
			, String pathToProgram
			, int runtimeInMili) {
        super(name);
        
        
        this.inputFilePath = inputFilePath;
        this.outputFilePath = outputFilePath;
        this.pathToProgram = pathToProgram;
        this.runtimeInMilli = runtimeInMili;
    }

	@Override
	public void handle(Object msg) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public Move move() throws Exception {
		
		// Update input file. 
		this.writeInputFile();
		
		// Start jar file
		Process p = Runtime.getRuntime().exec("java -jar " + this.pathToProgram + " -o " 
				+ this.outputFilePath + " -i " + this.inputFilePath + " -t " + runtimeInMilli);
		
		// Let current thread sleep while program is working
		Thread.sleep(runtimeInMilli + 50);
		
		// Destroy the programm
		p.destroy();
		
		// Now read the output File and bring it up to the game field
		return readOutputFile();
		
	}
	
	private AIMove readOutputFile() 
	{
		ArrayList<int[]> moves = new ArrayList<int[]>();
		
		BufferedReader reader = null;
		try 
		{
			// For safty, you have to compare input and output file for checking if the program worked
			
			reader = new BufferedReader(new FileReader(this.outputFilePath));
			
			
			String input = reader.readLine();      
			char initialPlayer = input.toCharArray()[0];
			if (initialPlayer != 'w' && initialPlayer != 'b')
			{
				reader.close();
				return null;
			}
			
			do
			{
				String[] stringMove = input.substring(2).split(",");
				int[] move = new int[2];
				move[0] = Integer.valueOf(stringMove[0]);
				move[1] = Integer.valueOf(stringMove[1]);
				moves.add(move);
				
			} while(!(input = reader.readLine()).startsWith("0"));
			
	        
			reader.close();
			
			SingleMove[] singleMoves = new SingleMove[moves.size()];
			for (int i = 0; i < moves.size(); i++) 
			{
				SingleMove move;
				
				//if ((this.getGame().getSnapshot().whitesTurn ? 'w' : 'b') == 'w')
				if (initialPlayer == 'w')
				{
					boolean beat = this.getOtherPlayer().getBoard()[moves.get(i)[1]] > 0;
					
					move = new SingleMove(this, 25 - moves.get(i)[0], 25 - moves.get(i)[1], beat);
				}
				else
				{
					boolean beat = this.getOtherPlayer().getBoard()[25 - moves.get(i)[1]] > 0;
					
					move = new SingleMove(this, moves.get(i)[0], moves.get(i)[1], beat);
				}
				singleMoves[i] = move;
			}
			
			
			return new AIMove(singleMoves, this);
		} 
		catch (IOException e) {
			System.out.println("Wrong filepath. Try again.");
			e.printStackTrace();
		}
		
		return null;
	}	

	private void writeInputFile()
	{
		StringBuilder inputBuilder = new StringBuilder();
		inputBuilder.append(this.getGame().getSnapshot().whitesTurn ? 'w' : 'b');
		inputBuilder.append(System.getProperty("line.separator"));
		inputBuilder.append(this.getGame().getDice()[0] + "," + this.getGame().getDice()[1]);
		inputBuilder.append(System.getProperty("line.separator"));
		inputBuilder.append(printBoard());
		
		File outputFile = new File(inputFilePath);	
		if (outputFile.exists())
		{
			outputFile.delete();
		}
 		try
 		{
			FileWriter writer = new FileWriter(inputFilePath ,false);
			writer.write(inputBuilder.toString());
			writer.close();	
		} 
 		catch (IOException e) 
		{
			e.printStackTrace();
		}
		
	}
	
	private String printBoard() 
	{
		int[] blackBoard = this.getGame().getSnapshot().getBlueBoard();
		int[] whiteBoard = this.getGame().getSnapshot().getWhiteBoard();
		
		
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < 26; i++) {
			int b = blackBoard[i];
			int w = whiteBoard[25 - i];
			
			sb.append(i);
			sb.append(':');
			sb.append('w');
			sb.append(w);
			sb.append(',');
			sb.append('b');
			sb.append(b);
			sb.append(System.getProperty("line.separator"));
		}
		return sb.toString();
	}
	
	@Override
	public int nextStep(boolean rollOnly) throws Exception {
		
		Thread.sleep(100);
		return ROLL;
	}

	@Override
	public boolean acceptsOffer(int offer) throws Exception {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isRemote() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void informRoll() throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void informMove(SingleMove move) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void informAccept(boolean answer) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean isWaitingForUIMove() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void animateMove(Move m) {
		// TODO Auto-generated method stub
		
	}

}
